package com.share.util.common;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.zip.*;

/**
 * 字符串压缩工具类
 * 提供gzip和zip两种压缩方式的编解码功能
 */
public class ZipUtils {

    private static final int BUFFER_SIZE = 1024;

    /**
     * 使用gzip进行压缩
     * @param primStr 原始字符串
     * @return 压缩后的Base64编码字符串，如果输入为空则返回原字符串
     */
    public static String gzip(String primStr) {
        if (primStr == null || primStr.isEmpty()) {
            return primStr;
        }

        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             GZIPOutputStream gzip = new GZIPOutputStream(out)) {

            gzip.write(primStr.getBytes(StandardCharsets.UTF_8));
            gzip.finish();
            return Base64.getEncoder().encodeToString(out.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException("Gzip compression failed", e);
        }
    }

    /**
     * 使用gzip进行解压缩
     * @param compressedStr 压缩后的Base64编码字符串
     * @return 解压后的字符串，如果输入为空则返回null
     */
    public static String gunzip(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }

        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayInputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(compressedStr));
             GZIPInputStream ginzip = new GZIPInputStream(in)) {

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = ginzip.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
            return out.toString(StandardCharsets.UTF_8.name());
        } catch (IOException e) {
            throw new RuntimeException("Gzip decompression failed", e);
        }
    }

    /**
     * 使用zip进行压缩
     * @param str 原始字符串
     * @return 压缩后的Base64编码字符串，如果输入为空则返回null
     */
    public static String zip(String str) {
        if (str == null) {
            return null;
        }

        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ZipOutputStream zout = new ZipOutputStream(out)) {

            zout.putNextEntry(new ZipEntry("0"));
            zout.write(str.getBytes(StandardCharsets.UTF_8));
            zout.closeEntry();
            return Base64.getEncoder().encodeToString(out.toByteArray());
        } catch (IOException e) {
            throw new RuntimeException("Zip compression failed", e);
        }
    }

    /**
     * 使用zip进行解压缩
     * @param compressedStr 压缩后的Base64编码字符串
     * @return 解压后的字符串，如果输入为空则返回null
     */
    public static String unzip(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }

        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayInputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(compressedStr));
             ZipInputStream zin = new ZipInputStream(in)) {

            zin.getNextEntry();
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            while ((bytesRead = zin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }
            return out.toString(StandardCharsets.UTF_8.name());
        } catch (IOException e) {
            throw new RuntimeException("Zip decompression failed", e);
        }
    }
}